package YAVMM::SortedAttributes;
use Moose::Role;
use MooseX::Method::Signatures;

use YAVMM::Types;

requires qw(sorted_attributes);

############################################################
# Usage      : $self->_sort_attributes($attributes);
# Purpose    : Return a list of sorted attributes with the given list
#            : in front.
# Returns    : Array[Moose::Meta::Attribute]
# Parameters : ArrayRef[Str] $attributes - list of attribute names
# Throws     : n/a
# Comments   : The idea is to return the list of attributes in a
#            : predefined order. The given list provides the initial
#            : ordering and any other attributes are returned in
#            : ascii-betical order.
# See Also   : $self->meta->get_all_attributes
#method _sort_attributes (ArrayRef[Str] $attributes) {
#    my $class = ref $self;
sub _sort_attributes {
    my $class      = shift;
    my $attributes = shift;

    my %attribs = ();
    foreach my $attr ($class->meta->get_all_attributes) {
	next if $attr->name =~ /\A _/x;
	$attribs{$attr->name} = $attr;
    }

    my @list = ();
    foreach my $name (@{ $attributes }) {
	if ($attribs{$name}) {
	    push @list, $attribs{$name};
	    delete $attribs{$name};
	}
    }

    push @list,
	sort { $a->name cmp $b->name} map { $attribs{$_} } keys %attribs;

    return @list;
}

1;

__END__

=head1 NAME

YAVMM::SortedAttributes - 

=head1 METHODS

=head2 sorted_attributes

Returns a list of public L<Moose::Meta::Attribute> objects from the
object sorted in the object's prefered order.

B<Note:> C<sorted_attributes()> may be called as a class method as well as
and instance method.

=head2 _sort_attributes(ArrayRef[Str] $attribute_names)

Returns the list of the object's public attributes in the order contained
in $attribute_names. Any additional public attributes are included in
alphabetical order.
